home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / dos / parsepattern.c < prev    next >
C/C++ Source or Header  |  1996-10-24  |  6KB  |  210 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: parsepattern.c,v 1.2 1996/10/24 15:50:34 aros Exp $
  4.     $Log: parsepattern.c,v $
  5.     Revision 1.2  1996/10/24 15:50:34  aros
  6.     Use the official AROS macros over the __AROS versions.
  7.  
  8.     Revision 1.1  1996/09/11 12:54:46  digulla
  9.     A couple of new DOS functions from M. Fleischer
  10.  
  11.     Desc:
  12.     Lang: english
  13. */
  14. #include <clib/exec_protos.h>
  15. #include <dos/dos.h>
  16. #include <dos/dosasl.h>
  17. #include "dos_intern.h"
  18.  
  19. /*****************************************************************************
  20.  
  21.     NAME */
  22.     #include <clib/dos_protos.h>
  23.  
  24.     AROS_LH3(LONG, ParsePattern,
  25.  
  26. /*  SYNOPSIS */
  27.     AROS_LHA(STRPTR, Source,      D1),
  28.     AROS_LHA(STRPTR, Dest,        D2),
  29.     AROS_LHA(LONG,   DestLength,  D3),
  30.  
  31. /*  LOCATION */
  32.     struct DosLibrary *, DOSBase, 140, Dos)
  33.  
  34. /*  FUNCTION
  35.     Takes a pattern containing wildcards and transforms it into some
  36.     intermediate representation for use with the MathPattern() function.
  37.     The intermediate representation is longer but generally a buffer
  38.     size of 2*(strlen(Source)+1) is enough. Nevertheless you should check
  39.     the returncode to be sure that everything went fine.
  40.  
  41.     INPUTS
  42.     Source     - Pattern describing the kind of strings that match.
  43.              Possible tokens are:
  44.              #x     - The following character or item is repeaded 0 or
  45.                       more times.
  46.              ?      - Item matching a single non-NUL character.
  47.              a|b|c  - Matches one of multiple strings.
  48.              ~x     - This item matches if the item x doesn't match.
  49.              (a)    - Parens
  50.              [a-z]  - Matches a single character out of the set.
  51.              [~a-z] - Matches a single non-NUL character not in the set.
  52.              'c     - Escapes the following character.
  53.              *      - Same as #?, but optional.
  54.     Dest       - Buffer for the destination.
  55.     DestLength - Size of the buffer.
  56.  
  57.     RESULT
  58.      1 - There are wildcards in the pattern (it might match more than
  59.          one string).
  60.      0 - No wildcards in it, all went fine.
  61.     -1 - An error happened. IoErr() gives additional information in
  62.          that case.
  63.  
  64.     NOTES
  65.  
  66.     EXAMPLE
  67.  
  68.     BUGS
  69.  
  70.     SEE ALSO
  71.  
  72.     INTERNALS
  73.  
  74.     HISTORY
  75.     29-10-95    digulla automatically created from
  76.                 dos_lib.fd and clib/dos_protos.h
  77.  
  78. *****************************************************************************/
  79. {
  80.     AROS_LIBFUNC_INIT
  81.     AROS_LIBBASE_EXT_DECL(struct DosLibrary *,DOSBase)
  82.     STRPTR stack, end;
  83.     UBYTE a, b, t;
  84.     LONG iswild=0;
  85.  
  86.     LONG *result=&((struct Process *)FindTask(NULL))->pr_Result2;
  87. #define ERROR(a) { *result=a; return -1; }
  88.     stack=end=Dest+DestLength;
  89. #define PUT(a) { if(Dest>=stack) ERROR(ERROR_BUFFER_OVERFLOW); *Dest++=(a); }
  90.     
  91.     if(!*Source)
  92.     {
  93.         PUT(0);
  94.         return 0;
  95.     }else
  96.         PUT(MP_OR);
  97.  
  98.     while(*Source)
  99.     {
  100.         switch(*Source++)
  101.         {
  102.             case '#':
  103.                 iswild=1;
  104.                 if(*Source=='?')
  105.                 {
  106.                     Source++;
  107.                     PUT(MP_ALL);
  108.                 }else
  109.                 {
  110.                     PUT(MP_MULT);
  111.                     *--stack=MP_MULT_END;
  112.                     continue;
  113.                 }
  114.                 break;
  115.             case '~':
  116.                 iswild=1;
  117.                 PUT(MP_NOT);
  118.                 *--stack=MP_NOT_END;
  119.                 continue;
  120.             case '?':
  121.                 iswild=1;
  122.                 PUT(MP_SINGLE);
  123.                 break;
  124.             case '(':
  125.                 PUT(MP_OR);
  126.                 *--stack=MP_OR_END;
  127.                 continue;
  128.             case '|':
  129.                 iswild=1;
  130.                 if(stack!=end&&*stack!=MP_OR_END)
  131.                     ERROR(ERROR_BAD_TEMPLATE);
  132.                 PUT(MP_OR_NEXT);
  133.                 break;
  134.             case ')':
  135.                 if(stack==end||*stack!=MP_OR_END)
  136.                     ERROR(ERROR_BAD_TEMPLATE);
  137.                 PUT(*stack++);
  138.                 break;
  139.             case '[':
  140.                 if(*Source=='~')
  141.                 {
  142.                     Source++;
  143.                     PUT(MP_NOT_SET);
  144.                 }else
  145.                     PUT(MP_SET);
  146.                 a=*Source++;
  147.                 if(!a)
  148.                     ERROR(ERROR_BAD_TEMPLATE);
  149.                 do
  150.                 {
  151.                     if(Source[0]=='-'&&Source[1]!=']')
  152.                     {
  153.                         Source++;
  154.                         b=*Source++;
  155.                         if(!b)
  156.                             ERROR(ERROR_BAD_TEMPLATE);
  157.                         if(b>a)
  158.                             t=a, a=b, b=t;
  159.                         PUT(MP_DASH);
  160.                         if(b>=0x81&&b<=0x8e)
  161.                         {
  162.                             PUT(MP_ESCAPE);
  163.                             b-=0x80;
  164.                         }
  165.                         PUT(b);
  166.                     }
  167.                     if(a>=0x81&&a<=0x8e)
  168.                     {
  169.                         PUT(MP_ESCAPE);
  170.                         a-=0x80;
  171.                     }
  172.                     PUT(a);
  173.                     a=*Source++;
  174.                     if(!a)
  175.                         ERROR(ERROR_BAD_TEMPLATE);
  176.                 }while(a!=']');
  177.                 PUT(MP_SET_END);
  178.                 break;
  179.             case '*':
  180.                 if(DOSBase->dl_Flags&RNF_WILDSTAR)
  181.                 {
  182.                     PUT(MP_ALL);
  183.                 }else
  184.                     PUT('*');
  185.                 break;
  186.             case '\'':
  187.                 if(!*Source++)
  188.                     ERROR(ERROR_BAD_TEMPLATE);
  189.                 /* Fall through */
  190.             default:
  191.                 a=Source[-1];
  192.                 if(a>=0x81&&a<=0x8e)
  193.                 {
  194.                     PUT(MP_ESCAPE);
  195.                     a-=0x80;
  196.                 }
  197.                 PUT(a);
  198.                 break;
  199.         }
  200.         while(stack!=end&&*stack!=MP_OR_END)
  201.             PUT(*stack++);
  202.     }
  203.     if(stack!=end)
  204.         ERROR(ERROR_BAD_TEMPLATE);
  205.     PUT(MP_OR_END);
  206.     PUT(0);
  207.     return iswild;
  208.     AROS_LIBFUNC_EXIT
  209. } /* ParsePattern */
  210.